Repository navigation
docs(workflows): use en dashes in the transactional email docs - #22166
Merged
Merged
Conversation
Replace the hyphen that separates a term from its description with an en dash, as the style guide and Vale's EnDash rule require. Change "rules that are easy to get wrong" to "rules that agents often get wrong". Leave the "Copies and attachments" list in api.mdx and the capture_engagement and engagement bullets alone: other open PRs rewrite those lines. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Contributor
Deploy preview
Changed pages
|
Contributor
|
Vale prose linter → found 3 errors, 15 warnings, 0 suggestions in your markdown Full report → Copy the linter results into an LLM to batch-fix issues. Linter being weird? Update the rules!
|
| Line | Severity | Message | Rule |
|---|---|---|---|
| 419:1 | error | Hi, Andy here... use an en dash ( – ) with spaces. On Mac, holding down the Option and hyphen key will give you an en dash. | PostHogBase.EnDash |
| 420:1 | error | Hi, Andy here... use an en dash ( – ) with spaces. On Mac, holding down the Option and hyphen key will give you an en dash. | PostHogBase.EnDash |
| 421:1 | error | Hi, Andy here... use an en dash ( – ) with spaces. On Mac, holding down the Option and hyphen key will give you an en dash. | PostHogBase.EnDash |
contents/docs/workflows/transactional-emails/dotnet.mdx — 0 errors, 2 warnings, 0 suggestions
| Line | Severity | Message | Rule |
|---|---|---|---|
| 79:94 | warning | Capitalize 'Feature Flags' for PostHog's product. Use 'feature flags' for the general industry concept. | PostHogBase.ProductNames |
| 127:20 | warning | 'Hangfire' is a possible misspelling. | PostHogBase.Spelling |
contents/docs/workflows/transactional-emails/elixir.mdx — 0 errors, 4 warnings, 0 suggestions
| Line | Severity | Message | Rule |
|---|---|---|---|
| 59:66 | warning | Capitalize 'Feature Flags' for PostHog's product. Use 'feature flags' for the general industry concept. | PostHogBase.ProductNames |
| 106:20 | warning | 'Oban' is a possible misspelling. | PostHogBase.Spelling |
| 172:336 | warning | 'EEx' is a possible misspelling. | PostHogBase.Spelling |
| 247:32 | warning | 'config's' is a possible misspelling. | PostHogBase.Spelling |
contents/docs/workflows/transactional-emails/go.mdx — 0 errors, 1 warnings, 0 suggestions
| Line | Severity | Message | Rule |
|---|---|---|---|
| 61:199 | warning | Capitalize 'Logs' for PostHog's product. Use 'logs' for the general industry concept. | PostHogBase.ProductNames |
contents/docs/workflows/transactional-emails/node.mdx — 0 errors, 1 warnings, 0 suggestions
| Line | Severity | Message | Rule |
|---|---|---|---|
| 54:72 | warning | Capitalize 'Feature Flags' for PostHog's product. Use 'feature flags' for the general industry concept. | PostHogBase.ProductNames |
contents/docs/workflows/transactional-emails/php.mdx — 0 errors, 1 warnings, 0 suggestions
| Line | Severity | Message | Rule |
|---|---|---|---|
| 59:67 | warning | Capitalize 'Feature Flags' for PostHog's product. Use 'feature flags' for the general industry concept. | PostHogBase.ProductNames |
contents/docs/workflows/transactional-emails/python.mdx — 0 errors, 1 warnings, 0 suggestions
| Line | Severity | Message | Rule |
|---|---|---|---|
| 73:89 | warning | Capitalize 'Feature Flags' for PostHog's product. Use 'feature flags' for the general industry concept. | PostHogBase.ProductNames |
contents/docs/workflows/transactional-emails/ruby.mdx — 0 errors, 2 warnings, 0 suggestions
| Line | Severity | Message | Rule |
|---|---|---|---|
| 56:215 | warning | Capitalize 'Logs' for PostHog's product. Use 'logs' for the general industry concept. | PostHogBase.ProductNames |
| 62:140 | warning | 'initializer' is a possible misspelling. | PostHogBase.Spelling |
contents/docs/workflows/transactional-emails/rust.mdx — 0 errors, 3 warnings, 0 suggestions
| Line | Severity | Message | Rule |
|---|---|---|---|
| 158:420 | warning | 'Askama' is a possible misspelling. | PostHogBase.Spelling |
| 158:430 | warning | 'Tera' is a possible misspelling. | PostHogBase.Spelling |
| 239:33 | warning | 'httpmock' is a possible misspelling. | PostHogBase.Spelling |
Contributor
Bundle reportTotal JS (gzip)12.07 MiB (+0.1 KiB / +0.0%) Eager graph (modules shipped in each entrypoint's initial chunks)
Largest modules in the
|
| Module | Size |
|---|---|
css ./node_modules/.pnpm/css-loader@5.2.7_webpack@5.101.3/node_modules/css-loader/dist/cjs.js??ruleSet[1].rules[8].oneOf[1].use[1]!./node_modules/.pnpm/postcss-loader@4.3.0_postcss@8.5.6_webpack@5.101.3/node_modules/postcss-loader/dist/cjs.js??ruleSet[1].rules[8].oneOf[1].use[2]!./src/styles/global.css |
1022.3 KiB |
./src/components/Stickers/Stickers.tsx |
696.4 KiB |
./node_modules/.pnpm/@posthog+icons@0.36.6_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@posthog/icons/dist/posthog-icons.es.js |
354.8 KiB |
./node_modules/.pnpm/react-markdown@8.0.7_@types+react@16.14.66_react@18.3.1/node_modules/react-markdown/lib/react-markdown.js + 88 modules |
351.4 KiB |
./node_modules/.pnpm/framer-motion@14.0.0_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/framer-motion/dist/es/render/components/motion/proxy.mjs + 126 modules |
287.2 KiB |
./node_modules/.pnpm/cloudinary-core@2.14.0_lodash@4.17.21/node_modules/cloudinary-core/cloudinary-core.js |
281.9 KiB |
./src/components/SearchUI/index.tsx + 87 modules |
273.1 KiB |
./gatsby-browser.tsx + 59 modules |
258.5 KiB |
./node_modules/.pnpm/@posthog+brand@0.13.0_react@18.3.1/node_modules/@posthog/brand/dist/generated/hoggies/svg/construction-1.mjs |
248.5 KiB |
./src/components/Pricing/PricingSlider/Slider.tsx + 87 modules |
240.2 KiB |
./node_modules/.pnpm/@posthog+brand@0.13.0_react@18.3.1/node_modules/@posthog/brand/dist/generated/hoggies/svg/construction-2.mjs |
228.2 KiB |
./node_modules/.pnpm/@posthog+brand@0.13.0_react@18.3.1/node_modules/@posthog/brand/dist/generated/hoggies/svg/magnifying-glass.mjs |
221.7 KiB |
./src/hooks/useProducts.tsx + 24 modules |
155.6 KiB |
./src/hooks/useProduct.ts + 9 modules |
149.4 KiB |
./src/components/Icons/Icons.tsx |
147.4 KiB |
Eager-graph budgets are report-only until a baseline is established. Sizes are gzip of public/**/*.js; eager size is webpack module source bytes for the modules actually shipped in the entrypoint's initial chunks (post-tree-shake).
…emails-en-dashes # Conflicts: # contents/docs/workflows/transactional-emails/node.mdx
#22088 merged and #22084 closed, so no open PR rewrites the capture_engagement, from, and engagement bullets any more. Change their hyphens to en dashes, and the hyphens in the new bullets that #22088 and #21984 added. The "Copies and attachments" list in api.mdx stays as it is. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Vale's EnDash rule needs a letter before " - ", so it misses a bullet whose term ends in bold or code, such as "**API** - Copy" and "**`text`** - If". The review panel found 9 of them. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Silthus
marked this pull request as ready for review
November 13, 2026 08:04
…emails-en-dashes # Conflicts: # contents/docs/workflows/transactional-emails/index.mdx
Silthus
added a commit
that referenced
this pull request
Nov 13, 2026
Vale's EnDash rule flags the bold-label bullets that this branch adds or changes. They now use an en dash, as master does since #22166. Refs PostHog/michaelr-context#88 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Silthus
added a commit
that referenced
this pull request
Nov 13, 2026
…email-sdk-attachments Brings in the en dashes of #22166 on the transactional email pages. Refs PostHog/michaelr-context#88 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2 of 3 tasks
Silthus
added a commit
that referenced
this pull request
Nov 13, 2026
* docs(workflows): add the transactional email API page Document how to make a Workflows email template transactional and send it with POST /api/projects/:project_id/messaging_templates/:template_id/send/. The page covers the API key, the request and response, idempotency keys, error codes, rate limits, and how transactional emails behave. The page is marked beta. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Generated-By: PostHog Desktop Task-Id: a0274fa0-d9be-48bf-b601-f153decf241d * docs(workflows): document the single send route, email status, and the SDKs - Send through `POST /messaging/send/email/` with `template.id`. The template route still works. - Read an email's status with `GET /messaging/emails/:message_id/`: statuses, reasons, 404 cases, scopes and read limits. - Send and read with the Python and Node.js SDKs. - Add `recipient_unreachable` to the errors table. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Generated-By: PostHog Desktop Task-Id: e72a2c10-f145-4f7c-8754-a4fcc06a18be * docs(workflows): fix vale findings on the transactional email page Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Generated-By: PostHog Desktop Task-Id: e72a2c10-f145-4f7c-8754-a4fcc06a18be * docs(workflows): address SDK review on the transactional email page - The Node.js example turns off local evaluation, and both examples keep the SDK's error. - The status examples handle the error first and explain retrying a not_found. - The SDK section adds install, client reuse, timeouts and retries, uncertain outcomes, and a no-network testing example. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Generated-By: PostHog Desktop Task-Id: e72a2c10-f145-4f7c-8754-a4fcc06a18be * docs(workflows): split transactional emails into overview and platform pages The overview keeps the template, key, idempotency, errors, statuses and behavior. Node.js, Python and API pages hold the setup, send, status, retries and testing for each platform, with a sidebar group like push notifications. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Generated-By: PostHog Desktop Task-Id: e72a2c10-f145-4f7c-8754-a4fcc06a18be * docs(workflows): add a quick start and the Transactional section to the overview - A quick start links to the Node.js, Python and API pages. - Creating an email follows the Transactional section's wizard, and the hidden workflow explanation is gone. - Agents can set it up with the PostHog MCP server. - Protect sensitive data turns off click tracking and keeps deliveries, opens and statuses. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Generated-By: PostHog Desktop Task-Id: e72a2c10-f145-4f7c-8754-a4fcc06a18be * docs(workflows): mention the per-send max_retries in Python Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Generated-By: PostHog Desktop Task-Id: e72a2c10-f145-4f7c-8754-a4fcc06a18be * docs(workflows): send template_id and distinct_id at the top of the body The send endpoint now takes a flat body (PostHog/posthog#126287), so the field table, the curl example and the engagement events note use template_id and distinct_id. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Generated-By: PostHog Desktop Task-Id: e72a2c10-f145-4f7c-8754-a4fcc06a18be * docs(workflows): send content from your code on the transactional email API page Document the code form of the send route (template_key with the subject and body), capture_engagement, the checks that only apply to it, and a delivery_unavailable anchor for the 503's docs link. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(workflows): list every reserved header and the header and tag limits Add DKIM-Signature and Received to the reserved headers, the header name and value limits, the tag length, and that reply_to takes bare addresses. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(workflows): say that a header name has no spaces Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(workflows): say that a header name has visible ASCII characters only Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(workflows): say what makes a code send the same request, and what template_key and ph_ tags do - A retry with the same Idempotency-Key is the same request when every field of the code-form table matches. - template_key groups the email's metrics and sends. - A tag name that starts with ph_, in any case, is refused. - capture_engagement on a template send defaults to the project's setting. - Drop a double blank line after the checks table (fix-mdx). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(workflows): list capture_engagement on the template send, and spell out the ph_ case rule - The template-send table gets a capture_engagement row with the project default, and says a retry sends the field the same way. - The code-form row keeps only its own default. - A ph_ tag name is refused in uppercase or lowercase. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(workflows): cut cc, bcc, headers, tags and attachments from the code send The first release sends content from code with template_key, subject, html and text only. React Email output is rendered by the app and sent as html. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(workflows): match the code form to the first send release - Drop capture_engagement from the template send: the send route refuses it there, with the other fields of content from your code. - Fold sender_not_allowed into sender_not_verified, the code the first release returns for a from address no verified sender can use. - Add "Send content from your code" to the Node.js and Python pages, with a React Email example rendered by the app. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(workflows): name the first release's field errors and the sender in a replay - A field error is a 400 with type validation_error, a field code such as required or invalid, and attr naming the field. - A replay also compares the sender PostHog chose, so a retry without from after the default sender changed returns idempotency_key_reused. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(workflows): link transactional emails to your users with the identify distinct ID Add "Link emails to your users" to the API, Node.js and Python pages: pass the distinct ID you pass to identify(), what happens without one today (a separate person keyed by the email address), and that invites and signup checks can leave it out. The overview and the API tables point there instead of "always send it". Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(workflows): say which signup email can leave out the distinct ID Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(workflows): match the link-emails section to the docs style rules Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(workflows): send transactional emails from Go, .NET, Rust, Ruby, Elixir and PHP Add a page for each SDK with the template send, content from code, the status read, and the distinct ID guidance. Copies and attachments are marked as coming in a later version. The API page shows every SDK in its language tabs. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(workflows): fix the SDK email snippets from the first review Use the placeholders the site fills in, pass the client to the Go and Ruby helpers, tell "not yet" from "not bounced" in Go, add the .NET usings and serde_json, and say that flag definitions still load from the ingestion host with the secret key. Ruby's timeout covers each connect, read, and write. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(workflows): fix the .NET import and status helpers from the second review Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(workflows): fill the SDK examples with the reader's token and host The Node.js and Python client examples used <ph_project_api_key> and a hard-coded ingestion host, which the site doesn't replace. They now use <ph_project_token> and <ph_client_api_host>, as the SDK pages do, so a logged-in reader sees their own project token and host. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(workflows): show copies and attachments for Rust and Ruby Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(workflows): show copies and attachments for PHP Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(workflows): show copies and attachments for .NET and drop the coming-soon notes Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(workflows): name the transactional_email scopes for sends and status reads A send needs transactional_email:write and a status read needs transactional_email:read or :write. Keys with a hog_flow scope still work. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(workflows): pick Transactional email in the key scopes list The key steps still picked Workflow, which creates a hog_flow key. The scopes list names the new scope Transactional email. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(workflows): make a template transactional with the transactional email scope Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(workflows): say to retry a status read right after a send A status read right after a send can answer 404 for a few seconds, until the send's first status arrives. Say so where the API page lists the 404, and that a retry after a short wait is the fix. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(workflows): name .NET SDK 2.20.0 as the first version with email Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(workflows): Python code sends start at 7.84.0 posthog-python#1171 ships as a minor bump, and PyPI is already at 7.83.2, so the code send arrives in 7.84.0, not 7.83.0. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(workflows): rewrite transactional email docs for a faster first send Add a quick start that sends a first email with curl, a table to choose where the content lives, a coding agent prompt on each SDK page, a retry column in the errors table, and a checklist for an email that didn't arrive. Each SDK page now shows a send from a background job, a test that fakes HTTP, and its proxy notes at the end. A new examples page covers sign-in codes, email address checks, invites, receipts with a PDF, and a funnel that measures an email. PHP names 4.22.0 and Elixir 2.20.0, the versions their releases now publish. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(workflows): keep job retries inside the idempotency key's 24 hours PostHog remembers an idempotency key for 24 hours, so a job retried after that can send the email twice. Each background-job example now says to finish its retries within 24 hours. The Sidekiq job retries 5 times, the River job has 5 attempts, and the BullMQ job shows its attempts and backoff. The quick start turns on Protect sensitive data for its reset email. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(workflows): add Node.js and Python attachments and fix the proxy note The Node.js and Python pages now document cc, bcc, and attachments, as the other six SDK pages do, and the receipt example shows Node.js and Python. Five pages said that the client never sends the secret key to a proxy, but local evaluation does. They now say that the client never sends email requests there. The Celery retries now wait long enough to pass a rate limit, and the quick start sets the key before it sends. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(workflows): hold SDK copies and attachments until the SDKs release them No SDK release sends cc, bcc, or attachments yet, so the SDK pages must not document them. The API takes them today, so the API page and the receipt example (cURL only) keep them. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(workflows): send copies and attachments from every SDK Restores the copies and attachments sections on the eight SDK pages, the Node.js and Python tabs of the receipt example, and the API page's note that the SDKs encode files for you. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(workflows): send email files by upload, then reference Content from your code attaches files that the sender uploaded first: hash each file, ask the upload route where to put it, PUT the missing ones, then send the hashes. The API page documents the upload route, the upload host for egress rules, and every refusal code. The SDK pages and the receipt example follow, and the limit reads 10 files and 40 MB per message after Base64 encoding, about 29 MB of files. The "temporarily unavailable" notes go. Refs PostHog/michaelr-context#88 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(workflows): link the upload host from every SDK page The SDKs upload to Amazon S3 too, so a reader behind an outgoing-traffic filter must find the host from their SDK's page. The host table gets its own heading on the API page, and each SDK section links to it. Refs PostHog/michaelr-context#88 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(workflows): fix the file checks and show refusals in the receipt script A 503 on a send can still mean the email is queued, so the checks for files no longer promise that nothing went out. The message_too_large row names the field path in attr, the send section links the checks for files, and the why and fix fields sit beside code and attr. The receipt script prints the upload route's refusal before it stops, and names shasum as a dependency. Refs PostHog/michaelr-context#88 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(workflows): say the upload limit counts when PostHog gives the URL Refs PostHog/michaelr-context#88 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(workflows): offer a link for new files over the upload limit Also name Python's attachments as dictionaries. Refs PostHog/michaelr-context#88 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(workflows): list the upload route's 404 and count the bodies at Base64 size Refs PostHog/michaelr-context#88 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(workflows): name the SDK versions that send copies and attachments Refs PostHog/michaelr-context#88 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(workflows): install the Rust SDK release that sends attachments The Rust page needs posthog-rs 0.33.0 for copies and attachments, so the install line now selects 0.33 instead of 0.32. Refs PostHog/michaelr-context#88 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(workflows): name the Python and .NET versions that send attachments Python 7.91.0 and .NET 2.25.0 are the first releases with the upload route. The .NET install line now pins 2.25.0, so the attachments example compiles. Refs PostHog/michaelr-context#88 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(workflows): send a calendar invite with content type parameters content_type now takes MIME parameters, such as method=REQUEST, so mail apps can show an .ics file as an invitation. A name or filename parameter gets not_mime_type, because the file name comes from filename. Refs PostHog/michaelr-context#88 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(workflows): show the calendar invite's content type without a scroll The one-line example hid the content_type value past the edge of the code block at every width. The file object now takes one line for each field, and the refusal of a name parameter follows the example. Refs PostHog/michaelr-context#88 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(workflows): use en dashes in the attachments bullets Vale's EnDash rule flags the bold-label bullets that this branch adds or changes. They now use an en dash, as master does since #22166. Refs PostHog/michaelr-context#88 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Harley Alexander <43975092+mayteio@users.noreply.github.com> Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
The transactional email docs use a hyphen ( - ) to separate a term from its description, as in "Host - Use ...". The style guide and Vale's
PostHogBase.EnDashrule need an en dash with spaces ( – ). On currentmaster, Vale reports 130 dash errors on these pages, so each PR that edits them gets a long Vale comment.This PR changes 136 spaced hyphens to en dashes: 127 of the 130 that Vale reports, and 9 that Vale misses because the term ends in bold or code, such as
**API** - Copy. That includes the new bullets from #22088 and #21984. It also changes one sentence on the 8 SDK pages, which Vale'sTrivializersrule flags: "the rules that are easy to get wrong" becomes "the rules that agents often get wrong". No text changes its meaning. No code block changes.This is a content PR, so it has no PR tour and no reviewer's guide.
Merge risk
Note
🔵 Merge risk: low · two-way door
git diff --word-diffshows only dashes and the one sentence. The dev server rendered all 10 pages.Lines that this PR does not change
api.mdx(3 dashes). Other work rewrites that section.Vale findings that this PR does not fix
These findings are false positives:
SpellingSpellingProductNamesProductNamesDirectAddressexamples.mdx)SentenceCaseChecks
.vale.inioncontents/docs/workflows/transactional-emails/:master(8198ff3): 130 errors, 24 warnings, 3 suggestions.git diff --word-diffagainstmastershows only two kinds of change: 136 hyphens to en dashes and 8 times the same sentence.git merge-treeagainst the head of each of the 8 open PRs that edit these pages: this PR adds no new conflict to any of them.--checkon the changed files passes.pnpm formatcovers only HTML, JS, TS, JSON, YAML, and CSS files, so it does not change.mdxfiles.pnpm format:docschanges lines that this PR does not own, one of them in a code block (#22167), so this PR does not include its output.pnpm starton545bc01, then all 10 pages in a browser. Each page showed the en dashes and the new sentence. Later commits change only more dashes in the same kind of list item.master. The React duplicate-key warnings in that list come from code blocks, which this PR does not change.qa-swarmpanel of 7 lenses (fresh eyes, correctness, risk, design, anti-overengineering, sweep, and a posthog.com docs-owner lens). Three lenses found the 9 bullets that Vale misses; this PR fixes them. The other lenses found nothing. PostHog Review found nothing.🤖 Generated with Claude Code